#include <string>
#include <iostream>
#include <vector>
#include "ast.h"
#include "semantic.h"

#include <boost/shared_ptr.hpp>
#include <boost/program_options.hpp>
namespace po = boost::program_options;

using namespace boost;

extern int yyparse();
extern FILE* yyin;
extern Program* syntaxResult;

shared_ptr<Program> program;

int main(int ac, char** av)
{
	bool only_parse = false;
	bool file = false;
	try {
		po::positional_options_description p;
		p.add("input-file", -1);

		po::options_description desc("TULC - Allowed options");
		desc.add_options()
				("help", "produce help message")
				("only-parse", "only parse the input file")
				("input-file", po::value< std::vector<std::string> >(), "input file")
		;

		po::variables_map vm;
		po::store(po::command_line_parser(ac, av).
          options(desc).positional(p).run(), vm);

		po::notify(vm);    

		if (vm.count("help")) {
				std::cout << desc << "\n";
				return 0;
		}
		if (vm.count("input-file")) {
				yyin = fopen( (vm["input-file"].as< std::vector<std::string> >())[0].c_str(), "r");
				if(yyin) file = true;
		}

		if (vm.count("only-parse")) {
			only_parse = true;
		}
		if(file) {
			std::cout << "Parsing phase" << std::endl;
			if(yyparse()) return 1;
			if(!only_parse) {
				std::cout << "Semantic analysis" << std::endl;
				program = shared_ptr<Program>(syntaxResult);
				SemanticAnalyser analyser(program);
				analyser.checkProgram();
			}
			return 0;
		}
		else {
				std::cout << desc << "\n";
				return 0;
		}
	}
	catch(std::exception& e) {
		 std::cerr << "error: " << e.what() << std::endl;
		 return 2;
	}
	catch(...) {
		std::cerr << "Unespected error!" << std::endl;
		return 3;
	}

	return 0;
}
